package oving8;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * This code is given to you. No changes are necessary, but you should look
 * through this class and try to understand what it does. In the exercise, you
 * are supposed to extends this class. Those of you already familiar with
 * abstract classes and methods: Correct, this is where it should have been
 * used.
 * 
 * Normally, this is where you would find a description of the class making it
 * unnecessary to read the rest of the code. Since that is the point, that
 * description is omitted. Often you will find code not documented at all. Try
 * to read this class now, and be sure to understand it at the end of the
 * exercise.
 * 
 * The SuppressWarnings annotation you could just ignore. It is there only to
 * make Eclipse shut up (it warns about SimplePanel being serializable, yet not
 * declaring a serial version id. I am not going to serialize a gui component,
 * so a ask Eclipse to ignore this warning).
 */
@SuppressWarnings("serial")
public class SimplePanel extends JPanel implements MouseListener,
		MouseMotionListener, KeyListener, ActionListener {

	/**
	 * Default constructor. It adds itself as listener to itself, and calls
	 * startAnimation().
	 */
	public SimplePanel() {
		addMouseListener(this);
		addMouseMotionListener(this);
		addKeyListener(this);
		startAnimation();
	}

	/**
	 * Timer objects are useful to do tasks again and again. You construct one
	 * with a time interval in ms, and an object implementing ActionListener.
	 * Then actionPerformed is called at those intervals.
	 */
	private Timer timer = null;

	/**
	 * This starts the animation, by constructing and starting a Timer object.
	 */
	protected void startAnimation() {
		if (timer == null) {
			timer = new Timer(1000, this);
		}
		timer.start();
	}

	/**
	 * This stops the animation by stopping the timer object.
	 */
	protected void stopAnimation() {
		if (timer != null) {
			timer.stop();
		}
	}

	/**
	 * This method from JComponent paints the JComponent on the Graphics object
	 * given. It is called by java when needed. This version calls
	 * paintPanel(Graphics2D), which you should implement, and protects you
	 * against some common pitfalls
	 * 
	 * @param g
	 *            is the Graphics object to paint on
	 * 
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		requestFocusInWindow();
		// this cast is always safe, as all newer versions of
		// java are using Graphics2D objects internally
		Graphics2D g2d = (Graphics2D) g;
		Color oldColor = g2d.getColor();
		AffineTransform transform = g2d.getTransform();
		paintPanel(g2d);
		g2d.setTransform(transform);
		g2d.setColor(oldColor);
	}

	/**
	 * This method you should override, description in the exercise
	 * 
	 * @param g
	 *            is the graphics object to paint on
	 */
	protected void paintPanel(Graphics2D g) {
	}

	/**
	 * This method you should override, description in the exercise
	 * 
	 * @param e
	 *            is the MouseEvent
	 */
	protected void mouseClick(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	protected void mousePress(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	protected void mouseRelease(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mouseDrag(MouseEvent e) {
	}

	/**
	 * This is called when the mouse is clicked inside this component. Calls
	 * mouseClick, which you should override and implement.
	 * 
	 * @param e
	 *            the event describing the click
	 * 
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	public void mouseClicked(MouseEvent e) {
		mouseClick(e);
		repaint();
	}

	/**
	 * This event is ignored
	 */
	public void mouseEntered(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mouseExited(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mousePressed(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mouseReleased(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mouseDragged(MouseEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void mouseMoved(MouseEvent e) {
	}

	/**
	 * This method is called every second, and you should override it.
	 * Description in the exercise.
	 */
	protected void tick() {
	}

	/**
	 * This is used by the timer to call tick() every second. It also repaints
	 * this component.
	 */
	public void actionPerformed(ActionEvent e) {
		tick();
		repaint();
	}

	/**
	 * This is a utility method for wrapping the given panel in a frame and
	 * displaying it on the screen. Use if you like!
	 * 
	 * @param panel the panel to wrap and display
	 */
	protected static void createFrame(SimplePanel panel) {
		JFrame frame = new JFrame("Shapes");
		frame.setContentPane(panel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400, 300);
		frame.setVisible(true);
	}

	/**
	 * This you should override and implement. Description in the exercise.
	 * @param e an object describing the key pressed event
	 */
	protected void keyPress(KeyEvent e) {
	}

	
	/** 
	 * This is called when this component has focus, and a key is pressed and released.
	 * Calls keyPress(KeyEvent e), which you should implement.
	 * 
	 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
	 */
	public void keyPressed(KeyEvent e) {
		keyPress(e);
		repaint();
	}

	/**
	 * This event is ignored
	 */
	public void keyReleased(KeyEvent e) {
	}

	/**
	 * This event is ignored
	 */
	public void keyTyped(KeyEvent e) {
	}
}
